-- Dda06defs.Dio v1.0
-- This Package contains the definitions of register addresses
-- and bit assignments for the 3 digital IO registers of the CIO-DDA06/Jr
-- card connected to the CAB board.

-- Also contains unchecked_conversion functions to convert register
-- records to Unsigned_8 which is needed when calling Write_IO_Port
-- in Io_Ports package.

-- Author : Rob Allen
-- version 1.0 19-May-08 created as a child of Dda06defs for digital IO registers
-- (incomplete!)
with Unchecked_Conversion; -- used for type conversions
with Unsigned_Types;  -- defines Unsigned_8 needed for compatiblity with Marte
with Raildefs;  -- for Dac_Id
--with train; --for turnout_preference
package Dda06defs.Dio is

   use Unsigned_Types, raildefs;
	 type Turnout_Preference_Type is (Left, Right, No_Preference);
   ----- Register I/O Addresses. ---------------------------------------------
   -- base address is "inherited" from parent package:
   --Base_Address : constant := 16#240#;

   PA_Addr   : constant := Base_Address + 12;
   PB_Addr   : constant := Base_Address + 13;
   PC_Addr   : constant := Base_Address + 14;
   Pctl_Addr   : constant := Base_Address + 15;

   Pctl_Init1 : constant Unsigned_Types.Unsigned_8 := 2#10011011#; -- Pa,Pb,Pc
   Pctl_Init2 : constant Unsigned_Types.Unsigned_8 := 2#00011011#; -- input

	Base_Address2 :constant := 16#310#;
    AD_hi: constant := Base_Address2 + 1;
    CS   : constant := Base_Address2 + 2;
    AUDIO: constant := Base_Address2 + 3;

   -- convenient array of IO addresses for regs:
   --
   subtype Controller_Id is Raildefs.Train_Id range 1..3;
   Reg_Addrs : constant array (Controller_Id) of Unsigned_16 :=
   (PA_Addr, PB_Addr, PC_Addr);

   ----- Declarations of Register Records, bit assignments -------------------

   type Controller_Bit is (On, Off);  -- note order 0=on, 1=off
   type Turnout_Pref_Reg is range 0..3;
	Reg_To_Pref : constant array (Turnout_Pref_Reg) of Turnout_Preference_Type :=
     (0|3=> No_Preference,
	 1=> Right,
	 2=> Left);
   type Register is record
      Horn : Controller_Bit;
	  Halt : Controller_Bit;
	  T_Pref: Turnout_Pref_Reg;
	  Dir : Controller_Bit;
   end record;
   for Register'Size use 8;
   for Register use record
      Horn at 0 range 0..0;
	  Halt at 0 range 1..1;
	  T_Pref at 0 range 3..4;
	  Dir at 0 range 2..2;
   end record;

   type CS_Register is record
      Eoc:Controller_Bit:=Off;
	  Hid:Natural range 0..7;
   end record;
   for CS_Register'Size use 8;
   for CS_Register use record
        Hid at 0 range 0..2;
        Eoc at 0 range 7..7;
   end record;

	type Dial_Value is range 0..63;--6 bits precision
	type Controller_State is
		record
			Dial:Dial_Value:=0;
			T_Pref:Turnout_Preference_Type:=No_Preference;
			Dir:Polarity_Type:=Fwd;
			Halt:Boolean:=false;
			Horn:Boolean:=false;
		end record;

    function Unsigned is new Unchecked_Conversion
      (   Source => CS_Register,
       Target => Unsigned_8);
    function Unsigned is new Unchecked_Conversion
      (   Source => Register,
       Target => Unsigned_8);
    function CS_Register_Convert is new Unchecked_Conversion
      (   Source => Unsigned_8,
       Target => CS_Register);
    function Register_Convert is new Unchecked_Conversion
      (   Source => Unsigned_8,
       Target => Register);
end Dda06defs.Dio;
